package demo

import (
	"fmt"
	"sync"
)

func init() {
	Register("ReplyMap", func() Service {
		return new(ReplyMap)
	})

	fmt.Println("ReplyMap registered")
}

type ReplyMap struct{}

// 创建一个双向映射的数据结构
type BiMap struct {
	mu               sync.RWMutex
	domainToRelyItem map[string][]string
	relyItemToDomain map[string][]string
}

func NewBiMap() *BiMap {
	return &BiMap{
		domainToRelyItem: make(map[string][]string),
		relyItemToDomain: make(map[string][]string),
	}
}

// 添加关联关系
func (bm *BiMap) AddRelation(domain string, relyItem string) {
	bm.mu.Lock()
	defer bm.mu.Unlock()

	bm.domainToRelyItem[domain] = appendIfMissing(bm.domainToRelyItem[domain], relyItem)
	bm.relyItemToDomain[relyItem] = appendIfMissing(bm.relyItemToDomain[relyItem], domain)
}

// 辅助函数：在切片中追加元素（如果尚不存在）
func appendIfMissing(slice []string, item string) []string {
	for _, v := range slice {
		if v == item {
			return slice
		}
	}
	return append(slice, item)
}

// 删除关联关系
func (bm *BiMap) DeleteRelation(domain, relyItem string) {
	bm.mu.Lock()
	defer bm.mu.Unlock()

	deleteFromSlice(bm.domainToRelyItem, domain, relyItem)
	deleteFromSlice(bm.relyItemToDomain, relyItem, domain)

	// 清理空的映射项
	if len(bm.domainToRelyItem[domain]) == 0 {
		delete(bm.domainToRelyItem, domain)
	}
	if len(bm.relyItemToDomain[relyItem]) == 0 {
		delete(bm.relyItemToDomain, relyItem)
	}
}

// 辅助函数：从切片中删除元素
func deleteFromSlice(m map[string][]string, key, item string) {
	if slice, exists := m[key]; exists {
		var newSlice []string
		for _, v := range slice {
			if v != item {
				newSlice = append(newSlice, v)
			}
		}
		m[key] = newSlice
	}
}

// 查询Domain关联的所有RelyItem
func (bm *BiMap) GetRelyItemsByDomain(domain string) []string {
	bm.mu.RLock()
	defer bm.mu.RUnlock()
	return bm.domainToRelyItem[domain]
}

// 查询RelyItem关联的所有Domain
func (bm *BiMap) GetDomainsByRelyItem(relyItem string) []string {
	bm.mu.RLock()
	defer bm.mu.RUnlock()
	return bm.relyItemToDomain[relyItem]
}

// 判断Domain是否存在
func (bm *BiMap) HasDomain(domain string) bool {
	bm.mu.RLock()
	defer bm.mu.RUnlock()

	_, exists := bm.domainToRelyItem[domain]
	return exists
}

// 判断RelyItem是否存在
func (bm *BiMap) HasRelyItem(relyItem string) bool {
	bm.mu.RLock()
	defer bm.mu.RUnlock()

	_, exists := bm.relyItemToDomain[relyItem]
	return exists
}

// 判断指定的RelyItem是否存在于给定Domain的映射列表中
func (bm *BiMap) HasRelyItemInDomain(domain string, relyItem string) bool {
	bm.mu.RLock()
	defer bm.mu.RUnlock()

	if _, exists := bm.domainToRelyItem[domain]; !exists {
		return false
	}

	for _, item := range bm.domainToRelyItem[domain] {
		if item == relyItem {
			return true
		}
	}
	return false
}

// 判断指定的Domain是否存在于给定RelyItem的映射列表中
func (bm *BiMap) HasDomainInRelyItem(relyItem string, domain string) bool {
	bm.mu.RLock()
	defer bm.mu.RUnlock()

	if _, exists := bm.relyItemToDomain[relyItem]; !exists {
		return false
	}

	for _, d := range bm.relyItemToDomain[relyItem] {
		if d == domain {
			return true
		}
	}
	return false
}

func (ec *ReplyMap) Exec() {
	biMap := NewBiMap()

	biMap.AddRelation("domain1", "relyItem1")
	biMap.AddRelation("domain1", "relyItem2")
	biMap.AddRelation("domain1", "relyItem3")
	biMap.AddRelation("domain2", "relyItem2")
	biMap.AddRelation("domain2", "relyItem3")
	biMap.AddRelation("domain3", "relyItem3")

	fmt.Println("Domain1关联的所有RelyItem:", biMap.GetRelyItemsByDomain("domain1"))
	fmt.Println("RelyItem2关联的所有Domain:", biMap.GetDomainsByRelyItem("relyItem2"))
}
